// 这个文件仅供node环境使用，在浏览器中 from "path" 会提示路径错误，需要写成 "./path"或"/path"或"../path"等
const path = require("path");
const fetch = require("./fetch");
const fs = require("fs");
const {
  writeFileSync,
  getSubPaths,
  addToFileLineSync,
  upperFirst,
  camelCase,
} = require("./base");
const { indexName, excludes, crawlerMap = {} } = require("../config");
const excludeList = [".vuepress", indexName, ...excludes];

module.exports = {
  /**
   * 删除某个文件夹下的所有内容(同步方法)
   * 注：nodejs不能一次性创建多层目录，需要递归处理
   * @param folderPath 多层目录路径 示例： hello/a/b/c
   * @param isDelSelf 是否删除自身文件夹，及目录路径的最后一级为空文件夹时，是否删除
   */
  deleteFolderSync(folderPath, isDelSelf = true) {
    if (fs.existsSync(folderPath)) {
      fs.readdirSync(folderPath).forEach((file, index) => {
        const curPath = path.join(folderPath, file);
        if (fs.lstatSync(curPath).isDirectory()) {
          // 如果是文件夹则递归删除
          deleteFolderSync(curPath, true);
        } else {
          // 如果是文件则直接删除
          fs.unlinkSync(curPath);
        }
      });
      isDelSelf && fs.rmdirSync(folderPath); // 删除空文件夹
    }
  },

  /**
   * 获取home页面的features
   * @param dirPath string 文件夹路径
   */
  getHomeFeatures(dirPath = "docs/") {
    const list = [];
    fs.readdirSync(dirPath).forEach((file, index) => {
      const curPath = path.join(dirPath, file);
      const isDir = fs.lstatSync(curPath).isDirectory(); //是否是文件夹
      if (isDir && !excludeList.includes(file)) {
        const name = crawlerMap[file]?.title || upperFirst(camelCase(file));
        list.push({
          title: `${name}`,
          details: `这是关于${name}的内容介绍。`,
        });
      }
    });
    return list;
  },

  /**
   * 获取顶部导航数据
   * @param dirPath string 文件夹路径
   */
  getHeadNavs(dirPath = "docs/") {
    const list = [];
    fs.readdirSync(dirPath).forEach((file, index) => {
      const curPath = path.join(dirPath, file);
      const isDir = fs.lstatSync(curPath).isDirectory(); //是否是文件夹
      if (isDir && !excludeList.includes(file)) {
        const name = crawlerMap[file]?.title || upperFirst(camelCase(file));
        list.push({
          text: name,
          link: `/${file}/`,
        });
      }
    });
    // list.push({ text: "Gitee", link: "https://google.com" });
    return list;
  },

  /**
   * 获取侧边栏导航数据
   * @param dirPath string 文件夹路径
   */
  getSideNavs(dirPath = "docs/") {
    const obj = {};
    fs.readdirSync(dirPath).map(async (file, index) => {
      const curPath = path.join(dirPath, file);
      // const isDir = fs.lstatSync(curPath).isDirectory(); //是否是文件夹
      if (!excludeList.includes(file)) {
        const paths = await getSubPaths(curPath);
        obj[`/${file}/`] = paths;
      }
    });
    return obj;
  },

  /**
   * 获取可爬取的所有name
   * @param excludes string[] 要排除的文件
   * @reture string[]
   */
  getCrawlerNames(excludes = excludeList) {
    const allNames = Object.keys(crawlerMap);
    return allNames.filter((item) => {
      return !excludes.includes(item);
    });
  },

  /**
   * 爬取html页面
   * @param url string 要爬取的url地址，例：https://git-scm.com/book/zh/v2
   * @param writePath string 要写入本地磁盘的文件地址，例：src/html/index.html
   */
  async fetchHtml(url = "", writePath, baseUrl = url) {
    try {
      return await fetch("GET", url).then((html) => {
        if (!html) {
          throw new Error("返回的html为空，有可能是地址错误：" + url);
        }
        html = addToFileLineSync(html, "<head>", [
          `  <base href="${baseUrl}" />`,
        ]);
        writePath && writeFileSync(writePath, html);
        return html;
      });
    } catch (err) {
      console.log(err);
      return "";
    }
  },
  /**
   * 下载图片
   * @param {string} url //要下载的图片地址
   * @param {string} writePath //要写入的文件地址（含文件格式，例如:.jpg）
   */
  async downloadImg(url, writePath) {
    return await fetch("GET", url, "binary")
      .then((res) => {
        const err = writeFileSync(writePath, res, "binary");
        console.log(`下载${err ? "失败" : "成功"}`, err || "");
        return null;
      })
      .catch((err) => {
        console.log("下载失败", err);
        return err;
      });
  },
};
